package br.com.websec.cnab;

import java.math.BigDecimal;
import java.util.Date;

import br.com.websec.banco.Banco;
import br.com.websec.util.CnabUtil;
import br.com.websec.util.FuncoesUtil;
import br.com.websec.util.UtilException;


public class Detalhe extends CnabUtil{
	
	private String codigoBanco;

	private int loteServico;

	private int registroCabecalho;

	private int tipoInscricaocEmpresa;

	private String cpfCnpjEmpresa;

	private String codigoConvenioBanco;

	private String agencia;
	
	private char aceite;

	private String digitoAgencia;

	private String posto;
	
	private String conta;

	private String digitoConta;

	private String digitoAgenciaConta;

	private String razaoSocialEmpresa;

	private String mensagem1;

	private String mensagem2;

	private Date dataCredito;
	
	private Date dataLiquidacao;

	private Integer codigoCarteira;
	
	private String codigoCarteiraCnab;

	private String identificacaoTitulo;
	
	private String variacaocarteira;

	private String identificacaoTituloEmpresa;

	private BigDecimal valorPercentualMulta;

	private String digitoNossoNumero;

	private int codigoMovimento;

	private String documentoCobranca;

	private Date dataVencimentoTitulo;

	private BigDecimal valorTitulo;

	private int especieTitulo;

	private Date dataEmissaoTitulo;

	private int codigoJuros;

	private BigDecimal valorJurosTaxa;

	private Date dataDesconto;

	private BigDecimal valorDesconto;

	private BigDecimal valorIOF;

	private BigDecimal valorAbatimento;

	private int tipoInscricaoCliente;

	private String cpfCnpjCliente;

	private String razaoSocialCliente;

	private String enderecoCliente;

	private String bairroCliente;

	private String cepCliente;

	private int sequencialRegistro;

	private String codigoRejeicoes;

	private BigDecimal valorJurosMulta;

	private BigDecimal valorAbatimentoCancelado;

	private BigDecimal valorPago;

	private BigDecimal valorLiquidacaoCredito;

	private BigDecimal valorOutrasDespesas;

	private BigDecimal valorOutrosCreditos;

	private BigDecimal valorOcorrenciaSacado;
	
	private Integer instrucoes;
	
	private Integer outrasInstrucoes;
	
	private String cidadeCliente;

	private String ufCliente;

	private int tipoInscricaoAvalista;

	private String cpfCnpjAvalista;

	private String razaoAvalista;

	private int identificacaoEmissaoBloqueto = 2;
	
	private int codigoProtesto = 0;
	
	private int diasProtesto = 0;
	
	private boolean descpont = false;
	
	public int getCodigoProtesto() {

		return codigoProtesto;
	}

	public BigDecimal calculaValorJuros(int codjur, BigDecimal valorapagar, BigDecimal percentual) {
		/**
		 * Código do juros de mora
		 * 1 - Valor por dia
		 * 2 - Taxa mensal
		 * 3 - Isento
		 */
		BigDecimal retorno = new BigDecimal(0);
		if (valorapagar!=null && percentual!=null && 
				percentual.doubleValue()>0 && valorapagar.doubleValue()>0 && 
				(codjur==1 || codjur==2) ) {
			if (codjur==1) {
			    retorno = valorapagar.multiply( percentual ).divide( new BigDecimal(100) );
			} else if (codjur==2) {
			    retorno = valorapagar.multiply( percentual ).divide( new BigDecimal(100) ) ;
			    retorno = retorno.divide( new BigDecimal(30), BigDecimal.ROUND_HALF_UP );
			}
		}
		return retorno;
	}
	
	/**
	 * Codigo para protesto.<br>
	 * 1 - Dias corridos.<br>
	 * 2 - Dias uteis.<br>
	 * 3 - Nao protestar.<br>
	 */
	public void setCodigoProtesto( final int codigoProtesto ) {

		this.codigoProtesto = codigoProtesto;
	}

	public int getDiasProtesto() {

		return diasProtesto;
	}

	/**
	 * Número de dias para protesto
	 */
	public void setDiasProtesto( final int diasProtesto ) {

		this.diasProtesto = diasProtesto;
	}
	
	public String getCpfCnpjCliente() {

		return cpfCnpjCliente;
	}

	public String getIdentificacaoTituloEmpresa() {

		return identificacaoTituloEmpresa;
	}

	public void setIdentificacaoTituloEmpresa( String identTitEmp ) {

		this.identificacaoTituloEmpresa = identTitEmp;
	}

	public BigDecimal getValorJurosMulta() {

		return valorJurosMulta;
	}

	public void setValorJurosMulta( BigDecimal valorJurosMulta ) {

		this.valorJurosMulta = valorJurosMulta;
	}

	public BigDecimal getValorAbatimentoCancelado() {

		return valorAbatimentoCancelado;
	}

	public void setValorAbatimentoCancelado( BigDecimal valorAbatimentoCancelado ) {

		this.valorAbatimentoCancelado = valorAbatimentoCancelado;
	}

	public BigDecimal getValorPago() {

		return valorPago;
	}

	public void setValorPago( BigDecimal valorPago ) {

		this.valorPago = valorPago;
	}

	public BigDecimal getValorLiquidacaoCred() {

		return valorLiquidacaoCredito;
	}

	public void setValorLiquidacaoCredito( BigDecimal valorLiqCred ) {

		this.valorLiquidacaoCredito = valorLiqCred;
	}

	public BigDecimal getValorOutrasDespesas() {

		return valorOutrasDespesas;
	}

	public void setValorOutrasDespesas( BigDecimal valorOutrasDespesas ) {

		this.valorOutrasDespesas = valorOutrasDespesas;
	}

	public BigDecimal getValorOutrosCreditos() {

		return valorOutrosCreditos;
	}

	public void setValorOutrosCreditos( BigDecimal valorOutrosCreditos ) {

		this.valorOutrosCreditos = valorOutrosCreditos;
	}

	public BigDecimal getValorOcorrenciaSacado() {

		return valorOcorrenciaSacado;
	}

	public void setValorOcorrenciaSacado( BigDecimal valorOcorrenciaSacado ) {

		this.valorOcorrenciaSacado = valorOcorrenciaSacado;
	}

	public String getCodigoRejeicoes() {

		return codigoRejeicoes;
	}

	public void setCodigoRejeicoes( String codigoRejeicoes ) {

		this.codigoRejeicoes = codigoRejeicoes;
	}

	public void setCpfCnpjCliente( String cpfCnpjCliente ) {

		this.cpfCnpjCliente = cpfCnpjCliente;
	}

	public int getSequencialregistro() {

		return sequencialRegistro;
	}

	public void setSequencialregistro( int sequencialregistro ) {

		this.sequencialRegistro = sequencialregistro;
	}

	public String getRazaoCliente() {

		return razaoSocialCliente;
	}

	public void setRazaoCliente( String razaoSocialCliente ) {

		this.razaoSocialCliente = razaoSocialCliente;
	}

	public String getEnderecoCliente() {

		return enderecoCliente;
	}

	public void setEnderecoCliente( String enderecoCliente ) {

		this.enderecoCliente = enderecoCliente;
	}

	public String getBairroCliente() {

		return bairroCliente;
	}

	public void setBairroCliente( String bairroCliente ) {

		this.bairroCliente = bairroCliente;
	}

	public String getCepCliente() {

		return cepCliente;
	}

	public void setCepCliente( String cepCliente ) {

		this.cepCliente = cepCliente;
	}

	public String getCidadeCliente() {

		return cidadeCliente;
	}

	public void setCidadeCliente( String cidadeCliente ) {

		this.cidadeCliente = cidadeCliente;
	}

	public String getUfCliente() {

		return ufCliente;
	}

	public void setUfCliente( String ufCliente ) {

		this.ufCliente = ufCliente;
	}

	public int getTipoInscricaoAvalista() {

		return tipoInscricaoAvalista;
	}

	public void setTipoInscricaoAvalista( int tipoInscricaoAvalista ) {

		this.tipoInscricaoAvalista = tipoInscricaoAvalista;
	}

	
	public Date getDataLiquidacao() {
	
		return dataLiquidacao;
	}

	
	public void setDataLiquidacao( Date dataLiquidacao ) {
	
		this.dataLiquidacao = dataLiquidacao;
	}

	public String getCpfCnpjAvalista() {

		return cpfCnpjAvalista;
	}

	public void setCpfCnpjAvalista( String cpfCnpjAvalista ) {

		this.cpfCnpjAvalista = cpfCnpjAvalista;
	}

	public String getRazaoAvalista() {

		return razaoAvalista;
	}

	public void setRazaoAvalista( String razaoAvalista ) {

		this.razaoAvalista = razaoAvalista;
	}

	public BigDecimal getValorJurosTaxa() {

		return valorJurosTaxa;
	}

	public int getTipoInscricaoCliente() {

		return tipoInscricaoCliente;
	}

	public void setTipoInscricaoCliente( int tipoInscricaoCliente ) {

		this.tipoInscricaoCliente = tipoInscricaoCliente;
	}

	public void setValorJurosTaxa( BigDecimal valorJurosTaxa ) {

		this.valorJurosTaxa = valorJurosTaxa;
	}

	public BigDecimal getValorAbatimento() {

		return valorAbatimento;
	}

	public void setValorAbatimento( BigDecimal valorAbatimento ) {

		this.valorAbatimento = valorAbatimento;
	}

	public BigDecimal getValorIOF() {

		return valorIOF;
	}

	public void setValorIOF( BigDecimal valorIOF ) {

		this.valorIOF = valorIOF;
	}

	public Date getDataDesconto() {

		return dataDesconto;
	}

	public BigDecimal getValorDesconto() {

		return valorDesconto;
	}

	public void setValorDesconto( BigDecimal valorDesc ) {

		this.valorDesconto = valorDesc;
	}

	public void setDataDesconto( Date dataDesconto ) {

		this.dataDesconto = dataDesconto;
	}

	public int getCodigoMovimento() {

		return codigoMovimento;
	}

	public int getCodigoJuros() {

		return codigoJuros;
	}

	public void setCodigoJuros( int codJuros ) {

		this.codigoJuros = codJuros;
	}

	public BigDecimal getValorTitulo() {

		return valorTitulo;
	}

	public int getEspecieTitulo() {

		return especieTitulo;
	}

	public Date getDataEmissaoTitulo() {

		return dataEmissaoTitulo;
	}

	public void setDataEmissaoTitulo( Date dataEmissaoTitulo ) {

		this.dataEmissaoTitulo = dataEmissaoTitulo;
	}

	public void setEspecieTitulo( int especieTitulo ) {

		this.especieTitulo = especieTitulo;
	}

	public void setValorTitulo( BigDecimal valorTitulo ) {

		this.valorTitulo = valorTitulo;
	}

	public void setCodigoMovimento( int codigoMovimento ) {

		this.codigoMovimento = codigoMovimento;
	}

	public Date getDataVencimentoTitulo() {

		return dataVencimentoTitulo;
	}

	public void setDataVencimentoTitulo( Date dataVencimentoTitulo ) {

		this.dataVencimentoTitulo = dataVencimentoTitulo;
	}

	public String getDocumentoCobranca() {

		return documentoCobranca;
	}

	public void setDocumentoCobranca( String documentoCobranca ) {

		this.documentoCobranca = documentoCobranca;
	}

	public String getDigNossoNumero() {

		return digitoNossoNumero;
	}

	public void setDigitoNossoNumero( String digitoNossoNumero ) {

		this.digitoNossoNumero = digitoNossoNumero;
	}

	public Detalhe() {

		setRegistroCabecalho( 1 );
	}

	public Detalhe( final String line ) throws UtilException {

		this();
		parseLine(line);
	}
	
	public String getAgencia() {

		return agencia;
	}

	public void setAgencia( final String agencia ) {

		this.agencia = agencia;
	}

	public char getAceite() {
	
		return aceite;
	}

	
	public void setAceite( char aceite ) {
	
		this.aceite = aceite;
	}

	public String getPosto() {
	
		return posto;
	}

	
	public void setPosto( String posto ) {
	
		this.posto = posto;
	}

	public String getCpfCnpjEmp() {

		return cpfCnpjEmpresa;
	}

	/**
	 * Inscricao da empresa. Conforme o tipo da inscricao.<br>
	 * 
	 */
	public void setCpfCnpjEmpresa( final String cpfCnpjEmpresa ) {

		this.cpfCnpjEmpresa = cpfCnpjEmpresa;
	}

	public String getCodigoBanco() {

		return codigoBanco;
	}

	public void setCodigoBanco( final String codigoBanco ) {

		this.codigoBanco = codigoBanco;
	}

	public String getCodigoConvenioBanco() {

		return codigoConvenioBanco;
	}

	/**
	 * Indentifica a empresa no banco para determinados tipos de servicos.<br>
	 * Observar as regras de preenchimento abaixo no que se refere ao cabecalho de servico/lote:<br>
	 * "9999999994444CCVVV " / 20 bytes / , onde:<br>
	 * 999999999 - Codigo do convenio.<br>
	 * 4444 - Codigo do produto.<br>
	 * CC - Carteira de cobranca.<br>
	 * VVV - Variacao da carteira de cobranca.<br>
	 */
	public void setCodigoConvenioBanco( final String codigoConvenioBanco ) {

		if (codigoConvenioBanco == null) {
		    this.codigoConvenioBanco = "";
		} else {
			this.codigoConvenioBanco = codigoConvenioBanco;
		}
	}

	public String getConta() {

		return conta;
	}

	public void setConta( final String conta ) {

		this.conta = conta;
	}

	public Date getDataCred() {

		return dataCredito;
	}

	public void setDataCredito( final Date dataCredito ) {

		this.dataCredito = dataCredito;
	}

	public String getDigitoAgenciaConta() {

		return digitoAgenciaConta;
	}

	public void setDigitoAgenciaConta( final String digAgeConta ) {

		this.digitoAgenciaConta = digAgeConta;
	}

	public String getDigAgencia() {

		return digitoAgencia;
	}

	public void setDigitoAgencia( final String digitoAgencia ) {

		this.digitoAgencia = digitoAgencia;
	}

	public String getDigitoConta() {

		return digitoConta;
	}

	public void setDigitoConta( final String digitoConta ) {

		this.digitoConta = digitoConta;
	}

	public int getLoteServico() {

		return loteServico;
	}

	/**
	 * Indentifica um Lote de Servico.<br>
	 * Sequencial e nao deve ser repetido dentro do arquivo.<br>
	 * As numeracoes 0000 e 9999 <br>
	 * sao exclusivas para o Cabecalho e para o Detalhe do arquivo respectivamente.<br>
	 */
	public void setLoteServico( final int loteServico ) {

		this.loteServico = loteServico;
	}

	public String getMensagem1() {

		return mensagem1;
	}

	/**
	 * As menssagens serao impressas em todos os bloquetos referentes 1 e 2 ao mesmo lote.<br>
	 * Estes campos nao serao utilizados no arquivo de retorno.<br>
	 */
	public void setMensagem1( final String mensagem1 ) {

		this.mensagem1 = mensagem1;
	}

	/**
	 * As menssagens ser�o impressas em todos os bloquetos referentes 1 e 2 ao mesmo lote.<br>
	 * Estes campos n�o ser�o utilizados no arquivo de retorno.<br>
	 */
	public String getMensagem2() {

		return mensagem2;
	}

	public void setMensagem2( final String mensagem2 ) {

		this.mensagem2 = mensagem2;
	}

	public String getRazaoEmpresa() {

		return razaoSocialEmpresa;
	}

	public void setRazaoEmpresa( final String razaoSocialEmpresa ) {

		this.razaoSocialEmpresa = razaoSocialEmpresa;
	}

	public int getRegistroCabecalho() {

		return registroCabecalho;
	}

	/**
	 * Indica o tipo de registro.<br>
	 */
	private void setRegistroCabecalho( final int registroCabecalho ) {

		this.registroCabecalho = registroCabecalho;
	}

	public int getTipoInscEmp() {

		return tipoInscricaocEmpresa;
	}

	/**
	 * Indica o tipo de inscricao da empresa.<br>
	 * 1 - CPF.<br>
	 * 2 - CNPJ.<br>
	 */
	public void setTipoInscricaoEmpresa( final int tipoInscricaocEmpresa ) {

		this.tipoInscricaocEmpresa = tipoInscricaocEmpresa;
	}

	public Integer getCodigoCarteira() {

		return codigoCarteira;
	}
	
	public String getVariacaoCarteira() {

		return variacaocarteira;
	}
	
	public void setVariacaoCarteira(String variacaocarteira) {

		this.variacaocarteira = variacaocarteira;
	}

	public void setCodigoCarteira( final Integer codCarteira ) {

		this.codigoCarteira = codCarteira;
	}

	public String getIdentTitulo() {

		return identificacaoTitulo;
	}

	/**
	 * Nosso numero.<br>
	 */
	public void setIdentificaoTitulo( final String identificacaoTitulo ) {

		this.identificacaoTitulo = identificacaoTitulo;
	}

	public BigDecimal getValorPercentualMulta() {

		return valorPercentualMulta;
	}

	public void setValorPercentualMulta( BigDecimal valorPercentualMulta ) {

		this.valorPercentualMulta = valorPercentualMulta;
	}

	public int getIdentificaoEmissaoBloqueto() {

		return identificacaoEmissaoBloqueto;
	}

	/**
	 * Identificacao da emissao de bloqueto.<br>
	 * 1 - Banco emite.<br>
	 * 2 - Cliente emite.<br>
	 * 3 - Banco pre-emite e o cliente completa.<br>
	 * 4 - Banco reemite.<br>
	 * 5 - Banco nao reemite.<br>
	 * 6 - Cobranca sem papel.<br>
	 * Obs.: Os campos 4 e 5 so serao aceitos para codigo de movimento para remessa 31.
	 */
	public void setIdentEmissaoBloqueto( final int identificacaoEmissaoBloqueto ) {

		this.identificacaoEmissaoBloqueto = identificacaoEmissaoBloqueto;
	}
	
	public String getCodigoCarteiraCnab() {
		return codigoCarteiraCnab;
	}

	
	public void setCodigoCarteiraCnab( String codigoCarteiraCnab ) {
		this.codigoCarteiraCnab = codigoCarteiraCnab;
	}

	
	public Integer getInstrucoes() {
	
		return instrucoes;
	}

	
	public void setInstrucoes( Integer instrucoes ) {
	
		this.instrucoes = instrucoes;
	}

	public boolean isDescpont() {
	
		return descpont;
	}

	
	public void setDescpont( boolean descpont ) {
	
		this.descpont = descpont;
	}

	public Integer getOutrasInstrucoes() {
	
		return outrasInstrucoes;
	}

	
	public void setOutrasInstrucoes( Integer outrasInstrucoes ) {
	
		this.outrasInstrucoes = outrasInstrucoes;
	}

	public String getLine( String padraocnab ) throws UtilException {

		StringBuilder line = new StringBuilder();

		try {
			if(getCodigoBanco().equals( Banco.ITAU )){
				return getLineItau( padraocnab );
			}
			
			if( getCodigoBanco().equals( Banco.BANCO_DO_BRASIL ) && (getCodigoConvenioBanco().length()>=7) ) {
				// Conv�nios menores que 1.000.000
				line.append( "7" ); // Tipo de registro 1	
				
			} else {
				line.append( "1" ); // Tipo de registro 1	
			}

			/*************************************************/
			/**                                             **/
			/** Implementacao para o Banco do Brasil CBR641 **/
			/**                                             **/
			/*************************************************/
			
			if(getCodigoBanco().equals( Banco.BANCO_DO_BRASIL )) {					
				line.append( formatar( getTipoInscEmp(), EnumTipo.$9, 2, 0 ) );// 002 a 003 - Tipo de inscricao da empresa
				line.append( formatar( getCpfCnpjEmp(), EnumTipo.$9, 14, 0 ) );//004 a 017 - Numero do CPF/CNPJ da Empresa
				line.append( formatar( getAgencia(), EnumTipo.$9, 4, 0 ) );//018 a 021 - Agencia
				line.append( formatar( getDigAgencia(), EnumTipo.X, 1, 0 ) );//022 a 022 - Digito da agencia
				line.append( formatar( getConta(), EnumTipo.$9, 8, 0 ) );//023 a 030 - Numero da conta corrente
				line.append( formatar( getDigitoConta(), EnumTipo.X, 1, 0 ) );//031 a 031 - Digito da conta corrente
				
				if (getCodigoConvenioBanco().length()<7) {
					line.append( formatar( getCodigoConvenioBanco(), EnumTipo.X, 6, 0 ) );//032 a 037 - Convenio
				} else {
					line.append( formatar( getCodigoConvenioBanco(), EnumTipo.X, 7, 0 ) );//032 a 038 - Convenio
				}
				line.append( formatar( getIdentificacaoTituloEmpresa(), EnumTipo.X, 25, 0 ) ); // Convenio < 1.000.000 = Posicao 38 a 62 - Nro de controle do participante (nosso numero)
																		    // Convenio >= 1.000.000 = Posicao 39 a 63	
				if (getCodigoConvenioBanco().length()<7) {
					// Convenio < 1.000.000
					line.append( formatar( getIdentTitulo(), EnumTipo.X, 11, 0 ) ); // Convenio < 1.000.000 = Posicao 063 a 073 - Nosso numero
					line.append( formatar( getDigNossoNumero(), EnumTipo.$9, 1, 0 ) ); // Posicao 074 a 074 - Digito verificador do nosso numero
				} else {
					// Convenio >= 1.000.000
					line.append( formatar( getIdentTitulo(), EnumTipo.X, 17, 0 ) ); // Conv�nio >= 1.000.000 = Posicao 064 a 080 - Nosso numero
				}
																			// Convenio >= 1.000.000 = Posicao 064 a 074 - Nosso numero
				line.append( "00" ); // Conv. < 100.000.00 = Posicao 075 a 076 / Conv >= 1.000.000 = Posicao 081 a 082 - Numero da prestacao informar zeros
				line.append( "00" ); // Posicao 077 a 078 / 083 a 084 - Grupo de valor informar zeros
				line.append( FuncoesUtil.replicate( " ", 3 ) );// Posicao 079 a 081 / 085 a 087 - Preencher com brancos
				line.append( " " );// Posicao 082 a 082 / 088 a 088 -Indicativo de mensagem Preencher com brancos
				line.append( FuncoesUtil.replicate( " ", 3 ) );// Posicao 083 a 085 / 089 a 091 - Preencher com brancos
				line.append( formatar( getVariacaoCarteira(), EnumTipo.X, 3, 0 ) ); // Posicao 086 a 088 / 092 a 094 - Variacao da carteira
				line.append( "0" ); // Posicao 089 a 089 / 095 a 095 - Conta caucao
				if (getCodigoConvenioBanco().length()<7) {
					line.append( "00000" ); // Posicao 090 a 094 - Codigo de responsabilidade
					line.append( "0" ); // Posicao 095 a 095 - Digito do codigo de responsabilidade
				} 
				line.append( "000000" ); // Posicao 096 a 101 - Numero do bordero
				line.append( FuncoesUtil.replicate( " ", 5 ) );// Posicao 102 a 106 - Tipo de cobranca Preencher com brancos
				line.append( FuncoesUtil.strZero( getCodigoCarteira() + "", 2 ) ); // Posicao 107 a 108 - Codigo da Carteira de Cobranca
				
			}
			
			/*************************************************/
			/**                                             **/
			/** 	Implementacao para banco (ITAU) 		**/
			/**                                             **/
			/*************************************************/
			
			else {
			
				line.append( FuncoesUtil.replicate( "0", 5 ) ); // Opcional - Agencia para debito em conta
				line.append( "0" ); // Opcional - Digito da Agencia para debito em conta
				line.append( FuncoesUtil.replicate( "0", 5 ) ); // Opcional - Razao da conta para debito
				line.append( FuncoesUtil.replicate( "0", 7 ) ); // Opcional - Conta do sacado para debito
				line.append( "0" ); // Opcional - Digito para conta de debito
				// Identificacao da Empresa cedente no banco
				line.append( "0" ); // Posicao 21 a 21 - Zero
				
				line.append( FuncoesUtil.strZero( getCodigoCarteira() + "", 3 ) ); // Posicao 22 a 24 - Codigo da Carteira
				line.append( formatar( getAgencia(), EnumTipo.$9, 5, 0 ) ); // Posicao 25 a 29 - Codigo da Agencia Cedente
				line.append( formatar( getConta(), EnumTipo.$9, 7, 0 ) ); // Posicao 30 a 36 - Conta Corrente
				line.append( formatar( getDigitoConta(), EnumTipo.X, 1, 0 ) ); // Posicao 37 a 37 - Digito da Conta
				// fim da idendificacao

				line.append( formatar( getIdentificacaoTituloEmpresa(), EnumTipo.X, 25, 0 ) ); // Posicao 38 a 62 - Nro de controle do participante (nosso numero)
				
				line.append(FuncoesUtil.replicate( "0", 3 ) ); // Posicao 63 a 65 - Nro do banco para debito em conta
				//line.append( format( getCodigoBanco(), ETipo.$9, 3, 0 ) ); // Posicao 63 a 65 - Nro do banco

				if ( getValorPercentualMulta().floatValue() > 0 ) {
					line.append( "2" ); // Posicao 66 a 66 - Se = 2 considerar multa se = 0 sem multa.
					line.append( formatar( getValorPercentualMulta(), EnumTipo.$9, 4, 2 ) ); // Posicao 67 a 70 - Percentual de multa
				}
				else {
					line.append( "0" ); // Posicao 66 a 66 - Se = 2 considerar multa se = 0 sem multa.
					line.append( FuncoesUtil.replicate( "0", 4 ) ); // Posicao 67 a 70 - Percentual de multa (preenchido com zeros)
				}

				line.append( formatar( getIdentTitulo(), EnumTipo.X, 11, 0 ) ); // Posicao 71 a 81 - Identificacao do titulo no banco (nosso numero)

				line.append( formatar( getDigNossoNumero(), EnumTipo.$9, 1, 0 ) ); // Posicao 82 a 82 - Digito verificador do nosso numero

				// Implementar futuramente
				line.append( formatar( 0, EnumTipo.$9, 10, 2 ) ); // Posicao 83 a 92 - Valor do Desconto bonif./dia

				line.append( formatar( getIdentificaoEmissaoBloqueto(), EnumTipo.$9, 1, 0 ) ); // Posicao 93 a 93 - Condicao para Emissao da papeleta de cobranca - 1-Banco emite e processa, 2- Cliente emite e o Banco Processa.

				line.append( "N" ); // Posicao 94 a 94 - Ident. se emite boleto para deb. automaticao

				line.append( FuncoesUtil.replicate( " ", 10 ) ); // Posicao 95 a 104 - Identificacao da operacao do banco (em branco)

				line.append( " " ); // Posicao 105 a 105 - Indicador de rateio credito 'R' = sim / " "= não
				line.append( "2" ); // Posicao 106 a 106 - Enderecamento para aviso do debito autom. 1 = emite aviso / 2 =nao emite

				line.append( FuncoesUtil.replicate( " ", 2 ) ); // Posicao 107 a 108 - Branco
				
			}
			
		

			line.append( formatar( getCodigoMovimento(), EnumTipo.$9, 2, 0 ) ); // Posicao 109 a 110 - Identificacao da ocorrencia

			line.append( FuncoesUtil.strZero( getDocumentoCobranca(), 10 ) ); // Posicao 111 a 120 - Nro do documento

			line.append( FuncoesUtil.dateToString( getDataVencimentoTitulo(), "DDMMAA" ) ); // Posicao 121 a 126 - Data do vencimento do título

			line.append( formatar( getValorTitulo(), EnumTipo.$9, 13, 2 ) ); // Posicao 127 a 139 - Valor do título

			if(getCodigoBanco().equals( Banco.BANCO_DO_BRASIL )) {	
				line.append( Banco.BANCO_DO_BRASIL ); // Posicao 140 a 142 - Banco encarregado da cobranca ( preencher com 001 )
				line.append( "0000" ); // Posicao 143 a 146 - Agencia deposit�ria ( preencher com zeros )
				line.append( " " ); // Posicao 147 a 147 - Digito Verificador do Prefixo da Agencia. Preencher com branco.
			}
			else {
				line.append( "000" ); // Posicao 140 a 142 - Banco encarregado da cobranca ( preencher com zeros )
				line.append( "00000" ); // Posicao 143 a 147 - Agencia depositaria ( preencher com zeros )
			}

			// line.append( format( getEspecieTit(), ETipo.$9, 2, 0 ) ); // Posicao 148 a 149 - Esp�cie de Titulo

			/*
			 * 01-Dulicata; 02-Nota Promissoria; 03-Nota de seguro 04-Cobranca seriada 05-Recibo 10-Letras de cambio 11-Nota de debito 12-Duplicata de serv. 99-Outros;
			 */
			line.append( formatar( getEspecieTitulo(), EnumTipo.$9, 2, 0 ) ); // Posicao 148 a 149 - Especie de titulo (Implementada de forma fixa pois difere do c�digo no padr�o cnab 240
//			line.append( format( "01", ETipo.$9, 2, 0 ) ); // Posicao 148 a 149 - Especie de Titulo (Implementada de forma fixa pois difere do c�digo no padr�o cnab 240

			line.append( "N" ); // Posicao 150 a 150 - Identificacao (Sempre "N");

			line.append( FuncoesUtil.dateToString( getDataEmissaoTitulo(), "DDMMAA" ) ); // Posicao 151 a 156 - Data de emiss�o do título

			/*

			if(getCodigoBanco().equals( Banco.BANCO_DO_BRASIL )) {
				
				line.append( format( getCodJuros(), ETipo.$9, 2, 0 ) ); // Posicao 157 a 158 - 1� Instru��o - Codigo para juros
				line.append( FuncoesUtil.strZero( getDiasProtesto() + "", 2 ) ); // Posicao 159 a 160 - 2� Instru��o - Numero de dias para protesto
				
			}
			else {
			*/
			line.append( formatar( getCodigoProtesto(), EnumTipo.$9, 2, 0 ) ); // Posicao 157 a 158 - 1� Instru��o - Codigo para juros
			line.append( FuncoesUtil.strZero( getDiasProtesto() + "", 2 ) ); // Posicao 159 a 160 - 2� Instru��o - Numero de dias para protesto
				
			//}

			if ( (getCodigoJuros()==1) || (getCodigoJuros()==2) ) { // Se Juros/Mora diaria
				line.append( formatar( calculaValorJuros(getCodigoJuros(), getValorTitulo(), getValorJurosTaxa()), EnumTipo.$9, 13, 2 ) ); // Posicao 161 a 173 - (se for do tipo mora diaria) Mora por dia de atraso
			}
			else {
				line.append( FuncoesUtil.replicate( "0", 13 ) ); // Posicao 161 a 173 - (Se n�o for do tipo mora di�ria) Mora por dia de atraso
			}

			if ( ( getCodigoBanco().equals( Banco.BANCO_DO_BRASIL ) ) || ( ! isDescpont() ) ) { // Revisar caso seja necess�rio implementar para Banco do Brasil
				line.append( "000000" ); // Posicao 174 a 179 - Data limite para concess�o de desconto (informar 000000)	
			}
			else{
				line.append( FuncoesUtil.dateToString( getDataDesconto(), "DDMMAA" ) ); // Posicao 174 a 179 - Data limete para concess�o de desconto
			}

			line.append( formatar( getValorDesconto(), EnumTipo.$9, 13, 2 ) ); // Posicao 180 a 192 - Valor de desconto

			line.append( FuncoesUtil.replicate( "0", 13 ) ); // Posicao 193 a 205 - (Valor do IOF (Apenas para empresas seguradoras))

			line.append( formatar( getValorAbatimento(), EnumTipo.$9, 13, 2 ) ); // Posicao 206 a 218 - Valor do Abatimento a ser concedido ou cancelado (no caso de transa��o de abatimento)

			line.append( FuncoesUtil.strZero( getTipoInscricaoCliente() + "", 2 ) );// Posicao 219 a 220 - Identificacao do tipo de inscricao do sacado -- 01:CPF, 02:CNPJ

			line.append( formatar( getCpfCnpjCliente(), EnumTipo.$9, 14, 0 ) );// Posicao 221 a 234 - CNPJ/CPF
			
			if(getCodigoBanco().equals( Banco.BANCO_DO_BRASIL )) {
				line.append( formatar( FuncoesUtil.LimpaString( FuncoesUtil.limpaAcentos( getRazaoCliente()), " " ).toUpperCase(), EnumTipo.X, 37, 0 ) );// Posicao 235 a 271 - Nome do Sacado
				line.append( FuncoesUtil.replicate( " ", 3 ) ); // Posicao 272 a 274 - Brancos
				line.append( formatar( FuncoesUtil.LimpaString( FuncoesUtil.limpaAcentos( getEnderecoCliente() ), " " ).toUpperCase(), EnumTipo.X, 52, 0 ) );// Posicao 275 a 326 - Endere�o Completo
			}
			else {
				line.append( formatar( getRazaoCliente(), EnumTipo.X, 40, 0 ) );// Posicao 235 a 274 - Nome do Sacado
				line.append( formatar( getEnderecoCliente(), EnumTipo.X, 40, 0 ) );// Posicao 275 a 314 - Endere�o Completo
				line.append( formatar( getMensagem1(),   EnumTipo.X, 12, 0 ) );// Posicao 315 a 326 - Mensagem 1
			}
			
			line.append( formatar( getCepCliente(), EnumTipo.$9, 8, 0 ) ); // Posicao 327 a 334 - Cep

			if(getCodigoBanco().equals( Banco.BANCO_DO_BRASIL )) {
				System.out.println("QUE MERDA");
				line.append( formatar( FuncoesUtil.limpaAcentos( getCidadeCliente() ).toUpperCase(), EnumTipo.X, 15, 0 ) );// Posicao 335 a 349 - Cidade do sacado
				line.append( formatar( getUfCliente(), EnumTipo.X, 2, 0 ) );// Posicao 350 a 351 - UF do sacado
				line.append( formatar( FuncoesUtil.LimpaString( FuncoesUtil.limpaAcentos( getRazaoAvalista()), " " ).toUpperCase(), EnumTipo.X, 40, 0 ) );// Posicao 352 a 391 - Sacado/Avalista ou Mensagem 2
				line.append( FuncoesUtil.replicate( " ", 2 ) ); // Posicao 392 a 393 - Informar Brancos
				line.append( " " ); // Posicao 394 a 394 - Brancos para completar registro
			}
			else {
				line.append( formatar( getRazaoAvalista(), EnumTipo.X, 60, 0 ) );// Posicao 335 a 394 - Sacado/Avalista ou Mensagem 2
			}
			
			line.append( formatar( getSequencialregistro(), EnumTipo.$9, 6, 0 ) );// Posicao 395 a 400 - N�o Sequencial do registro

			line.append( (char) 13 ); 

			line.append( (char) 10 );

		} catch ( Exception e ) {
			throw new UtilException( "CNAB registro 1.\nErro ao escrever registro.\n" + e.getMessage() );
		}

		return line.toString();
	}
	
	private String getLineItau(String padraocnab) throws UtilException{
		StringBuilder line = new StringBuilder();
		
		try{
			
			line.append( "1" ); // Tipo de registro 1	
			line.append( formatar( getTipoInscEmp(), EnumTipo.$9, 2, 0 ) );// 002 a 003 - Tipo de inscricao da empresa
			line.append( formatar( getCpfCnpjEmp(), EnumTipo.$9, 14, 0 ) );//004 a 017 - Numero do CPF/CNPJ da Empresa
			line.append( formatar( getAgencia(), EnumTipo.$9, 4, 0 ) );//018 a 021 - Agencia
			line.append( "00" );//022 a 023 - Digito da agencia
			line.append( formatar( getConta(), EnumTipo.$9, 5, 0 ) );//024 a 028 - Numero da conta corrente
			line.append( formatar( getDigitoConta(), EnumTipo.X, 1, 0 ) );//029 a 029 - Digito da conta corrente
			line.append( formatar( "", EnumTipo.X, 4, 0) );//030 a 033
			line.append( "0000" );//034 - 037
			line.append( formatar(getIdentificacaoTituloEmpresa(), EnumTipo.X, 25, 0 ) );//38 a 62
			line.append( formatar( getIdentTitulo(), EnumTipo.X, 8, 0 ) ); // 063 a 070 - Nosso numero
			line.append( "0000000000000"); // 71 a 83 - Quandtidade de moeda vari�vel -- Preencher com zeros para REAL.
			line.append( formatar( getCodigoCarteira(), EnumTipo.$9, 3, 0) );// 084 a 086 Numero da carteira no banco
			line.append( formatar( "", EnumTipo.X, 21, 0) );//087 a 107 Uso do banco 
			line.append( getCodigoCarteiraCnab() );//108 a 108
			line.append( formatar( getCodigoMovimento(), EnumTipo.$9, 2, 0 ) );//109 a 110 Identificacao da ocorrencia
			
			line.append( formatar( getDocumentoCobranca(), EnumTipo.X, 9, 0) );//111 a 120 Numero do documento

			line.append( FuncoesUtil.dateToString( getDataVencimentoTitulo(), "DDMMAA" ) ); // Posicao 121 a 126 - Data do vencimento do título
			line.append( formatar( getValorTitulo(), EnumTipo.$9, 13, 2 ) ); // Posicao 127 a 139 - Valor do título
			line.append( Banco.ITAU );//140 a 142
			line.append( "00000" );//143 a 147
			line.append( formatar( getEspecieTitulo(), EnumTipo.$9, 2, 0 ) ); // Posicao 148 a 149 - Esp�cie de T�tulo (Implementada de forma fixa pois difere do c�digo no padr�o cnab 240
			line.append( "N" ); // Posicao 150 a 150 - Identificacao (Sempre "N");
			line.append( FuncoesUtil.dateToString( getDataEmissaoTitulo(), "DDMMAA" ) ); // Posicao 151 a 156 - Data de emiss�o do título
			
			line.append( formatar( getCodigoProtesto(), EnumTipo.$9, 2, 0 ) ); // Posicao 157 a 158 - 1� Instru��o - Codigo para juros
			line.append( FuncoesUtil.strZero( getDiasProtesto() + "", 2 ) ); // Posicao 159 a 160 - 2� Instru��o - Numero de dias para protesto
			
			if ( (getCodigoJuros() == 1) || (getCodigoJuros() ==2 ) ) { // Se Juros/Mora di�ria
				line.append( formatar( calculaValorJuros(getCodigoJuros(), getValorTitulo(), getValorJurosTaxa()), EnumTipo.$9, 13, 2 ) ); // Posicao 161 a 173 - (se for do tipo mora di�ria) Mora por dia de atraso
			} else {
				line.append( FuncoesUtil.replicate( "0", 13 ) ); // Posicao 161 a 173 - (Se n�o for do tipo mora di�ria) Mora por dia de atraso
			}
			
			line.append( FuncoesUtil.dateToString( getDataDesconto(), "DDMMAA" ) ); // Posicao 174 a 179 - Data limete para concess�o de desconto
			line.append( formatar( getValorDesconto(), EnumTipo.$9, 13, 2 ) ); // Posicao 180 a 192 - Valor de desconto
			line.append( FuncoesUtil.replicate( "0", 13 ) ); // Posicao 193 a 205 - (Valor do IOF (Apenas para empresas seguradoras))
			line.append( formatar( getValorAbatimento(), EnumTipo.$9, 13, 2 ) ); // Posicao 206 a 218 - Valor do Abatimento a ser concedido ou cancelado (no caso de transa��o de abatimento)
			line.append( FuncoesUtil.strZero( getTipoInscricaoCliente() + "", 2 ) );// Posicao 219 a 220 - Identificacao do tipo de inscricao do sacado -- 01:CPF, 02:CNPJ
			line.append( formatar( getCpfCnpjCliente(), EnumTipo.$9, 14, 0 ) );// Posicao 221 a 234 - CNPJ/CPF
			line.append( formatar( getRazaoCliente(), EnumTipo.X, 30, 0 ) );// Posicao 235 a 264 - Nome do Sacado
			line.append( formatar( "", EnumTipo.X, 10, 0) );//Posicao 265 a 274
			line.append( formatar( getEnderecoCliente(), EnumTipo.X, 40, 0 ) );// Posicao 275 a 314
			line.append( formatar( getBairroCliente(), EnumTipo.X, 12, 0 ) );// Posicao 315 a 326
			line.append( formatar( getCepCliente(), EnumTipo.$9, 8, 0 ) );// Posicao 327 a 334
			line.append( formatar( getCidadeCliente(), EnumTipo.X, 15, 0 ) );// Posicao 335 a 349
			line.append( formatar( getUfCliente(), EnumTipo.X, 2, 0 ) );// Posicao 350 a 351
			line.append( formatar( getRazaoAvalista(), EnumTipo.X, 30, 0 ) );// Posicao 352 a 381
			line.append( formatar( "", EnumTipo.X, 4, 0 ) );// Posicao 382 a 385
			line.append( formatar( "", EnumTipo.$9, 6, 0 ) );// Posicao 386 a 391
			line.append( formatar( "", EnumTipo.$9, 2, 0 ) );// Posicao 392 a 393
			line.append( " " );// Posicao 394 a 394 Complemento brancos
			line.append( formatar( getSequencialregistro(), EnumTipo.$9, 6, 0 ) );// Posicao 395 a 400 - Numero Sequencial do registro
			
			line.append( (char) 13 ); 
			line.append( (char) 10 );

		} catch ( Exception e ) {
			throw new UtilException( "CNAB registro 1.\nErro ao escrever registro.\n" + e.getMessage() );
		}

		return FuncoesUtil.limpaAcentos( line.toString() );
	}
	
	public void parseLine( final String line ) throws UtilException {

		try {

			if ( line == null ) {
				throw new UtilException( "CNAB registro 1.\nLinha nula." );
			}
			
			else {

				if ( ("1".equals( line.substring( 0, 1 ) ) ) && ( Banco.ITAU.equals( getCodigoBanco() ) ) )  {
					parseLineItau(line);
				}
				else if ( "1".equals( line.substring( 0, 1 ) ) ) { // Posicao 01 a 01 - Identificacao do Registro DETALHE

					setCodigoCarteira(  new Integer( line.substring( 82, 85 ) ) ); // Posicao 83 a 85 - Numero da carteira
					setCodigoRejeicoes( line.substring( 108, 110 ) );// Posicao 109 a 110 - Codigo das ocorrencias

					setIdentificacaoTituloEmpresa( line.substring( 37, 62 ) ); // Posicao 38 a 62 - Nro Controle do Participante

					setValorOutrasDespesas( FuncoesUtil.strToBigDecimal( line.substring( 188, 201 ) ) );

					setValorJurosMulta( FuncoesUtil.strToBigDecimal( line.substring( 201, 214 ) ) );
					setValorIOF( FuncoesUtil.strToBigDecimal( line.substring( 214, 227 ) ) );
					setValorAbatimento( FuncoesUtil.strToBigDecimal( line.substring( 227, 240 ) ) );
					setValorDesconto( FuncoesUtil.strToBigDecimal( line.substring( 240, 253 ) ) );

					setValorPago( FuncoesUtil.strToBigDecimal( line.substring( 253, 266 ) ) );
					
//						setValorPago( FuncoesUtil.strToBigDecimal( line.substring( 305, 318 ) ) );
					
					setValorJurosTaxa( FuncoesUtil.strToBigDecimal( line.substring( 266, 279 ) ) );
					setValorOutrosCreditos( FuncoesUtil.strToBigDecimal( line.substring( 279, 292 ) ) );
					
					// Posicao 111 a 116 - Data da Entrada/Liquidacao (DDMMAA) 
					setDataLiquidacao( FuncoesUtil.stringToDateDDMMAA( line.substring( 110, 116 ).trim() ) );
											
					if(getCodigoBanco().equals( Banco.BANCO_DO_BRASIL )) {							
						//Posicao 176 a 181 -Data do Credito.
						setDataCredito( FuncoesUtil.stringToDateDDMMAA( line.substring( 175, 181 ).trim() ) );
						
					}
					else {
						setDataCredito( FuncoesUtil.stringToDateDDMMAA( line.substring( 295, 301 ).trim() ) );
					}
					
				
					System.out.println( "Rejeicao...." + line.substring( 86,88 ));
					
				} else if ( "7".equals( line.substring( 0, 1 ) ) ) { // Posicao 01 a 01 - Identificacao do Registro DETALHE

					setIdentificacaoTituloEmpresa( line.substring( 38, 63 ) ); // Posicao 39 a 63 - Nro Controle do Participante
					setCodigoCarteira(  new Integer( line.substring( 82, 85 ) ) ); // Posicao 83 a 85 - Numero da carteira
					setCodigoRejeicoes( line.substring( 108, 110 ) );// Posicao 109 a 110 - Codigo das ocorrencias (vide pg.45)
					//setValorPago( FuncoesUtil.strToBigDecimal( line.substring( 152, 165 ) ) ); // 153 a 165 - Valor do titulo 
					setValorOutrasDespesas( FuncoesUtil.strToBigDecimal( line.substring( 188, 201 ) ) ); // 189 a 201 - Outras despesas
					setValorJurosMulta( FuncoesUtil.strToBigDecimal( line.substring( 201, 214 ) ) ); // 202 a 214 - Juros do desconto
					setValorIOF( FuncoesUtil.strToBigDecimal( line.substring( 214, 227 ) ) ); // 215 a 227 - IOF do desconto
					setValorAbatimento( FuncoesUtil.strToBigDecimal( line.substring( 227, 240 ) ) ); // 228 a 240 - Valor do abatimento
					setValorDesconto( FuncoesUtil.strToBigDecimal( line.substring( 240, 253 ) ) ); // 241 a 253 - Desconto concedido 
					setValorPago( FuncoesUtil.strToBigDecimal( line.substring( 253, 266 ) ) ); // 254 a 266 - Valor recebido (valor recebido parcial)
					setValorJurosTaxa( FuncoesUtil.strToBigDecimal( line.substring( 266, 279 ) ) ); // 267 a 279 - Juros de mora
					setValorOutrosCreditos( FuncoesUtil.strToBigDecimal( line.substring( 279, 292 ) ) ); // 280 a 292 - Outros recebimentos
					
					setDataLiquidacao( FuncoesUtil.stringToDateDDMMAA( line.substring( 110, 116 ).trim() ) );
					
					if(getCodigoBanco().equals( Banco.BANCO_DO_BRASIL )) {
						setDataCredito( FuncoesUtil.stringToDateDDMMAA( line.substring( 175, 181 ).trim() ) ); // 176 a 181 - Data de credito (DDMMAA) 
						//setDataCred( FuncoesUtil.stringDDMMAAToDate( line.substring( 110, 116 ).trim() ) ); // 111 a 116 - Data de liquidacao (DDMMAA) 	
					}
					else {
						setDataCredito( FuncoesUtil.stringToDateDDMMAA( line.substring( 295, 301 ).trim() ) );
					}
					
					System.out.println( "Rejeicao...." + line.substring( 86,88 ));
				}
				else {
					//FuncoesUtil.mensagemInforma(erro, "erro");// !SSG
				}

			

			}
		} catch ( Exception e ) {
			throw new UtilException( "CNAB registro 1.\nErro ao ler registro.\n" + e.getMessage() );
		}
	}

	private void parseLineItau(final String line) throws UtilException {

		//seu numero
		setIdentificacaoTituloEmpresa( line.substring( 37, 62 ) ); // Posicao 38 a 62 - Nro Controle do Participante

		setCodigoRejeicoes( line.substring( 108, 110 ) );// Posicao 109 a 110 - Codigo das ocorrencias (vide pg.45)

		//Posicao 111 a 116 - Data de ocorrencia/liquidacao
		setDataLiquidacao( FuncoesUtil.stringToDateDDMMAA( line.substring( 110, 116 ).trim() ) );

	//	setValorIOF( FuncoesUtil.strToBigDecimal( line.substring( 214, 227 ) ) );
		setValorAbatimento( FuncoesUtil.strToBigDecimal( line.substring( 227, 240 ) ) );
		setValorDesconto( FuncoesUtil.strToBigDecimal( line.substring( 240, 253 ) ) );

		 //  254 a 266 - Valor lancado em conta corrente - Valor principal + o valor da cobranca 176-188
		setValorPago( FuncoesUtil.strToBigDecimal( line.substring( 253, 266 ) ).add( FuncoesUtil.strToBigDecimal( line.substring( 175, 188 ) ) ) ); 
		
		setValorJurosTaxa( FuncoesUtil.strToBigDecimal( line.substring( 266, 279 ) ) );
		
		setValorJurosMulta( FuncoesUtil.strToBigDecimal( line.substring( 279, 292 ) ) );
		
		//setValorOutrosCred( FuncoesUtil.strToBigDecimal( line.substring( 279, 292 ) ) );
		
		setDataCredito( FuncoesUtil.stringToDateDDMMAA( line.substring(  295, 301 ).trim() ) ); //Posicao 296 a 301 -Data do credito na conta corrente
		
	}

		
}
